﻿/*
 * Copyright © 2020, Wuxi Safover Intelligent Technology Co., Ltd. All rights reserved.
 * 
 * 无锡安永智能科技有限公司版权所有，未经许可，不得用于商业用途
 * 
 * Visit: https://www.safover.com/ 
 */

using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Safover.LidarCollector.Core
{
    public abstract class AcquisitionCard
    {
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        HashSet<ILidarDataListenner> Listenners { get; } = new HashSet<ILidarDataListenner>();

        readonly object locker = new object();

        public NetworkStatusChangedEventHandler NetworkStatusChanged { get; set; }

        public AcquisitionCardStatusChangedEventHandler AcquisitionCardStatusChanged { get; set; }

        public abstract bool IsConnected { get; }

        public abstract void KeepConnection();

        public abstract bool Disconnect();


        /// <summary>
        /// 配置采集卡参数并写入固件
        /// </summary>
        /// <param name="samplingDepth"></param>
        /// <param name="cumulativePulses"></param>
        /// <param name="channelId"></param>
        /// <returns></returns>
        public abstract bool InitParams(int samplingDepth, int cumulativePulses, int channelId = 0);

        /// <summary>
        /// 复位数据采集卡，清空当前数据
        /// </summary>
        /// <returns></returns>
        public abstract bool Reset();

        public abstract bool StartAcquisition();

        public abstract bool StopAcquisition();

        public void Subscribe(ILidarDataListenner listenner)
        {
            lock (locker)
            {
                if (!Listenners.Contains(listenner))
                {
                    Listenners.Add(listenner);
                }
            }
        }

        public void Unsubscribe(ILidarDataListenner listenner)
        {
            lock (locker)
            {
                if (Listenners.Contains(listenner))
                {
                    Listenners.Remove(listenner);
                }
            }
        }


        private void Notify(LidarDataCollectedEventArgs e)
        {
            ILidarDataListenner[] listenners;

            lock (locker)
            {
                listenners = Listenners.ToArray();
            }

            foreach (var listener in listenners)
            {
                try
                {
                    listener.NotifyLidarData(e);
                }
                catch (Exception ex)
                {
                    Log.Error(ex.Message);
                }
            }
        }

        protected void OnLidarDataRecieved(object sender, LidarDataReceivedEventArgs e)
        {
            Notify(new LidarDataCollectedEventArgs
            {
                ChannelNumber = e.ChannelNumber,
                CumulativePulses = e.CumulativePulses,
                SamplingDepth = e.SamplingDepth,
                Values = e.Values
            });
        }
    }


    public delegate void LidarDataReceivedEventHandler(object sender, LidarDataReceivedEventArgs e);
}
